
// import {WebGLRenderer} from "three";
import {
    WebGLRenderer, Scene, PerspectiveCamera,
    // Mesh, SphereGeometry, MeshStandardMaterial, MeshLambertMaterial, MeshBasicMaterial,
    Vector3, Vector2,
    //AxesHelper, GridHelper,
    // CylinderBufferGeometryAmbientLight,
    MOUSE,
    Object3D,
    Raycaster,
    // Light, ACESFilmicToneMapping,
} from "three";

import Stats from "three/examples/jsm/libs/stats.module";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"
import { TransformControls, } from 'three/examples/jsm/controls/TransformControls'

export class TEngine {
    private dom: HTMLElement;
    private renderer: WebGLRenderer

    private scene: Scene
    private camera: PerspectiveCamera
    private mouse: Vector2

    private transformControls: TransformControls

    constructor(_dom: HTMLElement) {

        console.log(_dom);
        var width = _dom.offsetWidth;
        var height = _dom.offsetHeight;

        this.dom = _dom;
        var renderer = new WebGLRenderer({ antialias: true });
        renderer.shadowMap.enabled = true;  //开启阴影


        var scene = new Scene();
        this.camera = new PerspectiveCamera(45, width / height, 0.1, 10000);
        this.camera.position.set(20, 20, 20);
        this.camera.lookAt(new Vector3(0, 0, 0))
        this.camera.up = new Vector3(0, 1, 0)

        //整个three渲染的界面  根据标签的大小一起变化
        // this.renderer.domElement.width =_dom.offsetWidth;
        // this.renderer.domElement.height = _dom.offsetHeight; 
        renderer.setSize(_dom.offsetWidth, _dom.offsetHeight, true);

        //背景色确定
        // this.renderer.setClearColor( 0xffffff)
        // this.renderer.clearColor();
        renderer.render(scene, this.camera);

        //性能监视器
        const stats = Stats();
        const statsDom = stats.domElement;
        statsDom.style.position = 'fixed';
        statsDom.style.top = '0px';
        statsDom.style.right = '5px';
        statsDom.style.left = 'unset';

        //创建视图轨道控制器
        const orbitControls = new OrbitControls(this.camera, renderer.domElement);
        orbitControls.autoRotate = false;  //不操作时自动旋转
        orbitControls.enableDamping = false; //拖动阻尼感
        orbitControls.mouseButtons = {
            LEFT: null as unknown as MOUSE,
            MIDDLE: MOUSE.DOLLY,
            RIGHT: MOUSE.ROTATE,
        }

        //添加变换控制
        const transControls = new TransformControls(this.camera, renderer.domElement)
        // const target = new Object3D();
        // transControls.attach(target);
        // scene.add(target);
        scene.add(transControls);

        //变换时锁定
        let transing = false;
        transControls.addEventListener('mouseDown', event => {
            transing = true;
        })

        document.addEventListener('keyup', event => {
            console.log(event.key);
            if (event.key === 'g') {
                transControls.mode = "translate";
                return false;
            }
            if (event.key === 's') {
                transControls.mode = "scale";
                return false;
            }
            if (event.key === 'r') {
                transControls.mode = "rotate";
                return false;
            }
        })

        //raycaster  
        var raycaster = new Raycaster();
        let cacheObject: Object3D | null = null;

        const mouse = new Vector2();
        let x = 0
        let y = 0
        let domW = 0;
        let domH = 0;
        renderer.domElement.addEventListener('mousemove', (event) => {
            // console.log(event.offsetX, event.offsetY);
            x = event.offsetX;
            y = event.offsetY;
            domW = renderer.domElement.offsetWidth;
            domH = renderer.domElement.offsetHeight;
            mouse.x = (x - domW * 0.5) / (domW * 0.5);;
            mouse.y = -(y - domH * 0.5) / (domH * 0.5);
            // console.log(mouse.x, mouse.y);
            raycaster.setFromCamera(mouse, this.camera);
            const intersection = raycaster.intersectObjects(scene.children);
            if (intersection.length) {
                // console.log(intersection);
                const object = intersection[0].object;
                //从 其他物体 或 空 进入新物体
                if (object !== cacheObject) { 
                    //若是本来有投射的物体则启用mouseleave 
                    if (cacheObject) {  
                        cacheObject.dispatchEvent({
                            type: 'mouseleave'
                        });
                    }
                    //凡是进入新物体 启动 mouseenter
                    object.dispatchEvent({
                        type: 'mouseenter'
                    });
                }
                else if (object === cacheObject) {
                    object.dispatchEvent({
                        type: 'mousemove'
                    });
                }
                cacheObject = object;
            }
            else { 
                if (cacheObject) {  
                    cacheObject.dispatchEvent({
                        type: 'mouseleave'
                    });
                }
                cacheObject = null;
             }
        });
        renderer.domElement.addEventListener('click', (event) => {
            if (transing) { transing = false; return false; }  //变换时锁定 若在变换则依靠结束的click解锁
            raycaster.setFromCamera(mouse, this.camera);

            //去除先前的变换控制器的影响
            scene.remove(transControls);
            var intersection = raycaster.intersectObjects(scene.children);
            //选择完成后再次加入控制器
            scene.add(transControls);

            if (intersection.length) {
                var object = intersection[0].object;
                transControls.attach(object);
                console.log(object);
            }
        });





        //渲染函数
        const animate = () => {
            // console.log(1)
            // ball.position.x += 0.005;
            //轨道控制器更新
            orbitControls.update();

            //需要将变换完成后才能渲染
            renderer.render(scene, this.camera);
            requestAnimationFrame(animate);
            //性能检测
            stats.update();
        }
        animate();

        //加入dom
        this.dom.appendChild(renderer.domElement);
        this.dom.appendChild(statsDom);

        this.renderer = renderer;
        this.scene = scene;
        this.transformControls = transControls;
        this.mouse = mouse;
    }

    clearScene() {
        this.scene.children.forEach((item) => { this.scene.remove(item); })
    }

    //添加几何体的方法
    addObject(...object: Object3D[]) {
        object.forEach(elem => {
            this.scene.add(elem);
        });
    }

    //添加光源的方法
    addLight(...object: Object3D[]) {
        object.forEach(elem => {
            this.scene.add(elem);
        });
    }

    //添加辅助的方法
    addHelper(...object: Object3D[]) {
        object.forEach(elem => {
            this.scene.add(elem);
        });
    }


}